﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Drawing;
using System.Xml.Linq;
using System.Xml.XPath;

namespace UCL
{
    /// <summary>
    /// 外观主题帮助类
    /// </summary>
    /// <remarks>2014-1-5 by sutroon重构,支持外观文件定义,需增加Skin/{TemplateName}/UI.uif文件</remarks>
    /// <example>
    /// SoSkinHelper.Install(Application.StartupPath,PicResource.Skin,true);
    /// SoSkinHelper.AddTimer(DateTime.Parse("2014-1-20"), DateTime.Parse("2014-2-14"), "Chunjie2014");
    /// SoSkinHelper.Read();
    /// if (!SoSkinHelper.Enable)
    /// {
    ///    MessageBox.Show(SoSkinHelper.Message.ToString(Environment.NewLine));
    /// }
    /// this.BackgroundImage = SoSkinHelper.GetBackgroundImageById("frmLogin");
    /// </example>
    public class SoSkinHelper
    {
        // 主题XML文件
        private static XElement UIDoc;

        // 本地主题文件夹目录,本地主题配置内容,应用程序根目录
        private static string _SkinDir, _skinConf,_appRoot;

        /// <summary>
        /// 获取或设置鼠标划过的图片标签
        /// </summary>
        public static string ImageHoverTag { get; set; }

        /// <summary>
        /// 获取或设置鼠标点击的图片标签
        /// </summary>
        public static string ImageClickTag { get; set; }

        /// <summary>
        /// 获取或设置默认主题名称
        /// </summary>
        public static string DefaultSkinID { get; set; }

        /// <summary>
        /// 获取或设置当前主题名称
        /// </summary>
        public static string CurrentSkinID { get; set; }

        /// <summary>
        /// 获取或设置主题是否可用
        /// </summary>
        public static bool Enable { get; set; }

        /// <summary>
        /// 获取或设置消息
        /// </summary>
        public static IList<string> Message { get; set; }

        /// <summary>
        /// 切换到指定名称的主题
        /// </summary>
        /// <param name="skinid"></param>
        public static void SwitchSkin(string skinid)
        {
            // 写入缓存
            CurrentSkinID = skinid;
            SaveConf(skinid);

            // 检测环境
            if (_SkinDir == null) _SkinDir = _appRoot + "\\Skin\\" + skinid;
            string uifile = _SkinDir + "\\UI.uif";
            if (!Directory.Exists(_SkinDir) || !File.Exists(uifile))
            {
                Enable = false;
                Message.Add(string.Format("未设置主题样式![{0}]", skinid));
                return;
            }
            Enable = true;

            try
            {
                UIDoc = XElement.Load(uifile);
            }
            catch (Exception ex)
            {
                Message.Add(ex.Message);
                Enable = false;
                throw ex;
            }

        }

        // 获取属性值
        private static string GetAttrValue(string id, string attrid, bool showErr = true, string[] tags = null)
        {
            if (!Enable) return null;
            XElement xe = UIDoc.XPathSelectElement(string.Format("//*[@id='{0}']", id));
            if (xe == null)
            {
                if (showErr) Message.Add(string.Format("id [{0}] 无索引!", id));
                return null;
            }
            if (xe.Attribute(attrid) == null)
            {
                if (showErr) Message.Add(string.Format("id [{0}] 资源文件不存在!", id));
                return null;
            }
            return tags == null ? xe.Attribute(attrid).Value : string.Format(xe.Attribute(attrid).Value, tags);
        }

        // 获取指定编号的替换图片
        private static Image GetAltImageById(string id, string attrid, string altattrid, string suffix)
        {
            string path = GetAttrValue(id, attrid, false);
            if (string.IsNullOrEmpty(path)) path = GetAttrValue(id, altattrid);
            if (string.IsNullOrEmpty(path)) return null;
            if (!path.Contains('\\')) path = _SkinDir + "\\" + path;
            string ext = Path.GetExtension(path);
            string path1 = path.Substring(0, path.LastIndexOf('.')) + suffix + ext;
            if (File.Exists(path1)) return Bitmap.FromFile(path1);
            if (!File.Exists(path)) return null;
            return Bitmap.FromFile(path);
        }

        // 获取指定编号的图片
        public static Image GetImageById(string id, string attrid = "Image", string[] tags = null)
        {
            string path = GetAttrValue(id, attrid, true, tags);
            if (string.IsNullOrEmpty(path)) return null;
            if (!path.Contains('\\')) path = _SkinDir + "\\" + path;
            if (!File.Exists(path)) return null;
            return Bitmap.FromFile(path);
        }

        // 获取指定编号的鼠标划过替换图片
        public static Image GetImageHoverById(string id, string attrid = "ImageHover", string altattrid = "Image")
        {
            return GetAltImageById(id, attrid, altattrid, ImageHoverTag);
        }

        // 获取指定编号的鼠标点击时的替换图片
        public static Image GetImageClickById(string id, string attrid = "ImageClick", string altattrid = "Image")
        {
            return GetAltImageById(id, attrid, altattrid, ImageClickTag);
        }

        // 获取指定编号的背景图片
        public static Image GetBackgroundImageById(string id, string attrid = "BackgroundImage")
        {
            return GetImageById(id, attrid);
        }

        /// <summary>
        /// 获取指定编号的颜色
        /// </summary>
        /// <param name="id"></param>
        /// <param name="attrid"></param>
        /// <returns></returns>
        /// <remarks>2014-1-9 created by sutroon</remarks>
        public static Color GetColorById(string id, string attrid)
        {
            string color = GetAttrValue(id, attrid);
            if (string.IsNullOrEmpty(color)) return Color.Empty;
            try
            {
                if (color.StartsWith("#")) return ColorTranslator.FromHtml(color);
                if (color.Contains(','))
                {
                    string[] arr = color.Split(',');
                    return Color.FromArgb(arr[0].ToInt(), arr[1].ToInt(), arr[2].ToInt());
                }
                return Color.FromName(color);
            }
            catch (Exception ex)
            {
                Message.Add(ex.Message);
                return Color.Empty;
            }
        }

        /// <summary>
        /// 获取指定编号的背景颜色
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Color GetBackColorById(string id)
        {
            return GetColorById(id, "BackColor");
        }

        /// <summary>
        /// 安装主题文件
        /// </summary>
        /// <param name="appRoot"></param>
        /// <param name="zip"></param>
        /// <param name="coverOld">是否覆盖原主题文件</param>
        public static void Install(string appRoot, byte[] zip, bool isOverwrite= true)
        {
            // 初始化皮肤列表
            dtTimer = new System.Data.DataTable();
            dtTimer.Columns.Add("SkinID");
            dtTimer.Columns.Add("Begin", typeof(DateTime));
            dtTimer.Columns.Add("Finish", typeof(DateTime));


            // 初始化属性
            DefaultSkinID = "Default";
            ImageHoverTag = "_hover";
            ImageClickTag = "_click";
            Message = new List<string>();

            _appRoot = appRoot;
            _skinConf = appRoot + "\\Skin\\Skin.conf";

            // 建立目录
            string dir = appRoot + "\\Skin";
            if (!isOverwrite && Directory.Exists(dir)) return;
            FileHelper fh = new FileHelper();
            try
            {
                fh.UnZip(zip, dir);
            }
            catch (Exception ex)
            {
                Message.Add(ex.Message);
            }
        }

        static DataTable dtTimer;

        /// <summary>
        /// 添加计时器
        /// </summary>
        /// <param name="dtBegin"></param>
        /// <param name="dtFinish"></param>
        /// <param name="skinid"></param>
        /// <remarks>2014-1-9 by sutroon</remarks>
        public static void AddTimer(DateTime dtBegin, DateTime dtFinish, string skinid)
        {
            dtTimer.Rows.Add(skinid, dtBegin, dtFinish);
        }

        /// <summary>
        /// 读取本地主题文件内容
        /// </summary>
        public static void Read()
        {
            if (File.Exists(_skinConf))
            {
                DefaultSkinID = File.ReadAllText(_skinConf);
                SwitchSkin(DefaultSkinID);
                return;
            }
            if (dtTimer != null)
            {
                foreach (DataRow r in dtTimer.Rows)
                {
                    if (DateTime.Now > (DateTime)r[1] && DateTime.Now < (DateTime)r[2])
                    {
                        SwitchSkin(r[0].ToString());
                        return;
                    }
                }
            }
            SwitchSkin(DefaultSkinID);
        }

        /// <summary>
        /// 保存主题配置
        /// </summary>
        /// <param name="skinid"></param>
        /// <remarks>2014-1-10 by sutroon</remarks>
        public static void SaveConf(string skinid)
        {
            File.WriteAllText(_skinConf, skinid);
        }
    }
}
